#include "um.h"

TOB::UI_UM::UI_UM(UIConfig &c): Mod(c) {}
TOB::UI_UM::~UI_UM() {}

// Run
void TOB::UI_UM::run() {
  username = config.username;
  UM::Client um(config.nsip, config.username, config.password);
  US us(config.nsip);

  UIMenu menum(0, 1, config.offsetX, 0);
  UIWindow statusw(0, 0, 0, 1);
  UIWindow labelw(config.offsetX + 1, 1, 0, 0);

#ifdef ADM
  UIText logint (config.offsetX + 1, 2,          0, 1);
  logint.lines[0] = CONVERT(username); logint.printBlock();
  UIText rolet  (config.offsetX + 1, 8, 0, 1);
  UIText policyt(config.offsetX + 1, 10, 0, 1);
#endif
  UIText namet  (config.offsetX + 1, 2 + OFFSET, 0, 1);
  UIText passt  (config.offsetX + 1, 4 + OFFSET, 0, 1);
  passt.password = true;

  // Save pointer
  this->um = &um;
  this->statusw = &statusw;
  this->menum = &menum;

  // Set labels
  labelw.setColor(Color::Green);
#ifdef ADM
  labelw.setCursor(0, 0); labelw.putString(config.lang["um-username"]);
  labelw.setCursor(0, 6); labelw.putString(config.lang["um-role"]);
  labelw.setCursor(0, 8); labelw.putString(config.lang["um-policy"]);
#endif
  labelw.setCursor(0, 0 + OFFSET); labelw.putString(config.lang["um-name"]);
  labelw.setCursor(0, 2 + OFFSET); labelw.putString(config.lang["um-pass"]);

  //
  // Go back
  menum.insert(config.lang["back"], [&]() {
    menum.running = false;
  });

  //
  // Edit data
  menum.insert(config.lang["enter"], [&]() {
#ifdef ADM
    logint.focus(); 
    username = CONVERT(logint.lines[0]);
#endif
    namet.focus();
    passt.focus();
#ifdef ADM
    rolet.focus();
    policyt.focus();
#endif
    menum.showCursor(false);
  });

  //
  // Load data
  menum.insert(config.lang["um-load"], [&]() {
    std::string data;
#ifdef ADM
    int32 idata;
    if(us.getUintByLogin(username, "role", idata) == Code::Okay) {
      std::string tmp = roleToString((Role::Type)idata);
      rolet.lines[0] = CONVERT(tmp); rolet.printBlock();
    }
    if(us.getUintByLogin(username, "policy", idata) == Code::Okay) {
      std::string tmp = policyToString((Policy::Type)idata);
      policyt.lines[0] = CONVERT(tmp); policyt.printBlock();
    }
#endif
    if(us.getStringByLogin(username, "name", data) == Code::Okay) {
      namet.lines[0] = CONVERT(data); namet.printBlock();
    }
  });

#ifdef ADM
  //
  // Add user
  menum.insert(config.lang["um-add"], [&]() {
    std::string pass = CONVERT(passt.lines[0]);
    std::string role = stringToRole(CONVERT(rolet.lines[0]));
    std::string policy = stringToPolicy(CONVERT(policyt.lines[0]));
    std::string name = CONVERT(namet.lines[0]);
    if(um.createUser(username, pass, role, policy, name) == Code::Okay) {
      status(config.lang["success"]);
    } else {
      status(config.lang["failure"]);
    }
  });

  //
  // Delete user
  menum.insert(config.lang["um-delete"], [&]() {
    if(um.deleteUser(username) == Code::Okay) {
      status(config.lang["success"]);
    } else {
      status(config.lang["failure"]);
    }
  });

  // 
  // Change role
  menum.insert(config.lang["um-change-role"], [&]() {
    if(um.changeFieldByLogin(username, "role", 
        stringToRole(CONVERT(rolet.lines[0]))) == Code::Okay) {
      status(config.lang["success"]);
    } else {
      status(config.lang["failure"]);
    }
  });

  // 
  // Change policy
  menum.insert(config.lang["um-change-policy"], [&]() {
    if(um.changeFieldByLogin(username, "policy", 
        stringToPolicy(CONVERT(policyt.lines[0]))) == Code::Okay) {
      status(config.lang["success"]);
    } else {
      status(config.lang["failure"]);
    }
  });
#endif

  // 
  // Change name
  menum.insert(config.lang["um-change-name"], [&]() {
    if(um.changeFieldByLogin(username, "name", CONVERT(namet.lines[0])) == Code::Okay) {
      status(config.lang["success"]);
    } else {
      status(config.lang["failure"]);
    }
  });

  // Set title
  String str;
  status(str);
  menum.focus();
}


// Set status
void TOB::UI_UM::status(String &msg) {
  statusw->setCursor(0, 0);
  statusw->clearLine();
  statusw->setColor(Color::Title);
  String out = config.lang["user-management"] + config.lang["delim"] + msg;
  statusw->putString(out);
}


// Role -> String
std::string TOB::UI_UM::roleToString(Role::Type role) {
  switch(role) {
   case Role::User: return "user";
   case Role::Administrator: return "administrator";
   default: return "";
  }
}


// Policy -> String
std::string TOB::UI_UM::policyToString(Policy::Type policy) {
  std::string out;
  if(policy & Policy::AllowUserManagement) { out += "um "; } 
  if(policy & Policy::AllowMail) { out += "em "; } 
  if(policy & Policy::AllowFileSharing) { out += "fs "; } 
  if(policy & Policy::AllowCalendar) { out += "cl "; } 
  if(policy & Policy::AllowToDo) { out += "td "; } 
  if(policy & Policy::AllowDirectory) { out += "dr "; } 
  if(policy & Policy::AllowTime) { out += "tm "; } 
  if(policy & Policy::AllowWebServer) { out += "ws "; } 
  if(policy & Policy::AllowChat) { out += "ct "; } 
  return out;
}


// String -> Role
std::string TOB::UI_UM::stringToRole(std::string in) {
  if(in == "administrator") { return "1"; }
  else if(in == "user") { return "0"; }
  return "0";
}


// String -> Policy
std::string TOB::UI_UM::stringToPolicy(std::string in) {
  Policy::Type out = (Policy::Type)0;
  if(in.find("um") != std::string::npos) { out |= Policy::AllowUserManagement; }
  if(in.find("em") != std::string::npos) { out |= Policy::AllowMail; }
  if(in.find("fs") != std::string::npos) { out |= Policy::AllowFileSharing; }
  if(in.find("cl") != std::string::npos) { out |= Policy::AllowCalendar; }
  if(in.find("td") != std::string::npos) { out |= Policy::AllowToDo; }
  if(in.find("dr") != std::string::npos) { out |= Policy::AllowDirectory; }
  if(in.find("tm") != std::string::npos) { out |= Policy::AllowTime; }
  if(in.find("ws") != std::string::npos) { out |= Policy::AllowWebServer; }
  if(in.find("ct") != std::string::npos) { out |= Policy::AllowChat; }
  std::stringstream outs;
  outs << (int32)out;
  return outs.str();
}
